/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package AIReservation;

/**
 *
 * @author micheal
 */
import java.awt.Point;

class StrategyReserved
{

    int RandNumber(int i)
    {
        nnn += mmm;
        nnn = nnn % 39;
        kkk += nnn;
        kkk = kkk % 31;
        mmm += 7;
        mmm = mmm % 1017;
        nnn += mmm;
        nnn = nnn % 39;
        kkk += nnn;
        kkk = kkk % 31;
        return kkk % i;
    }

    void ComputeWeight(int i, int j, int k, int ai[][])
    {
        int l = 0;
        int i1 = 0;
        do
        {
            int j1 = POSI(i, i1, 4);
            int l1 = POSJ(j, i1, 4);
            if(ON_BOARD(j1, l1, k))
            {
                l = ComputeIndex5(i, j, i1, ai);
                for(int j2 = index5[l]; j2 > 0; j2 /= 150)
                {
                    Pattern pattern = patterns[j2 % 150 - 1];
                    int i3 = pattern.offset;
                    j1 = POSI(i, i1, i3);
                    l1 = POSJ(j, i1, i3);
                    if(ai[j1][l1] == 0)
                        weights[j1][l1] += pattern.weight;
                }

            }
            j1 = POSI(i, i1, 5);
            l1 = POSJ(j, i1, 5);
            if(ON_BOARD(j1, l1, k))
            {
                int k2 = ComputeIndex6(i, j, i1, l, ai);
                for(int l2 = index6[k2]; l2 > 0; l2 /= 150)
                {
                    Pattern pattern1 = patterns[l2 % 150 - 1];
                    int j3 = pattern1.offset;
                    int k1 = POSI(i, i1, j3);
                    int i2 = POSJ(j, i1, j3);
                    if(ai[k1][i2] == 0)
                        weights[k1][i2] += pattern1.weight;
                }

            }
        } while(++i1 < 8);
    }

    StrategyReserved()
    {
        weights = new int[30][30];
        kkk = 1;
        mmm = 7;
        nnn = 13;
        dirI[0] = -1;
        dirI[1] = dirJ[3] = 0;
        dirI[2] = dirI[3] = dirJ[0] = dirJ[1] = dirJ[2] = dirI[7] = 1;
        dirI[4] = dirJ[6] = 0;
        dirJ[4] = dirI[5] = dirJ[5] = dirI[6] = dirJ[7] = -1;
        patterns[0] = new Pattern(0x5f5e164, "*xxxx");
        patterns[1] = new Pattern(0x5f5e164, "x*xxx");
        patterns[2] = new Pattern(0x5f5e164, "xx*xx");
        patterns[3] = new Pattern(0x186a2, "*xxx-");
        patterns[4] = new Pattern(0x186a2, "*x-xx");
        patterns[5] = new Pattern(0x186a2, "*xx-x");
        patterns[6] = new Pattern(0x15f90, "*-xxx");
        patterns[7] = new Pattern(0x186a2, "x*-xx");
        patterns[8] = new Pattern(0x186a2, "x*x-x");
        patterns[9] = new Pattern(0x186a2, "x*xx-");
        patterns[10] = new Pattern(0x15f92, "-*xxx");
        patterns[11] = new Pattern(0x186a2, "-x*xx");
        patterns[12] = new Pattern(0x186a2, "x-*xx");
        patterns[13] = new Pattern(1002, "*x-x-");
        patterns[14] = new Pattern(1002, "*x--x");
        patterns[15] = new Pattern(1502, "*xx--");
        patterns[16] = new Pattern(1000, "*-x-x");
        patterns[17] = new Pattern(1000, "*--xx");
        patterns[18] = new Pattern(1000, "*-xx-");
        patterns[19] = new Pattern(1002, "x*--x");
        patterns[20] = new Pattern(1002, "x*-x-");
        patterns[21] = new Pattern(1002, "x*x--");
        patterns[22] = new Pattern(1000, "-*x-x");
        patterns[23] = new Pattern(1502, "-*xx-");
        patterns[24] = new Pattern(1000, "-*-xx");
        patterns[25] = new Pattern(1000, "x-*-x");
        patterns[26] = new Pattern(1002, "-x*-x");
        patterns[27] = new Pattern(1002, "-x*x-");
        patterns[28] = new Pattern(1502, "--*xx");
        patterns[29] = new Pattern(1, "*--x-");
        patterns[30] = new Pattern(1, "*---x");
        patterns[31] = new Pattern(53, "*x---");
        patterns[32] = new Pattern(50, "*-x--");
        patterns[33] = new Pattern(1, "-*--x");
        patterns[34] = new Pattern(50, "-*-x-");
        patterns[35] = new Pattern(53, "-*x--");
        patterns[36] = new Pattern(53, "x*---");
        patterns[37] = new Pattern(53, "--*x-");
        patterns[38] = new Pattern(50, "--*-x");
        patterns[39] = new Pattern(1, "*--o-");
        patterns[40] = new Pattern(1, "*---o");
        patterns[41] = new Pattern(53, "*o---");
        patterns[42] = new Pattern(50, "*-o--");
        patterns[43] = new Pattern(1, "-*--o");
        patterns[44] = new Pattern(50, "-*-o-");
        patterns[45] = new Pattern(53, "-*o--");
        patterns[46] = new Pattern(53, "o*---");
        patterns[47] = new Pattern(53, "--*o-");
        patterns[48] = new Pattern(50, "--*-o");
        patterns[49] = new Pattern(0x5f5e100, "oo*oo");
        patterns[50] = new Pattern(0x5f5e100, "o*ooo");
        patterns[51] = new Pattern(0x5f5e100, "*oooo");
        patterns[52] = new Pattern(0x186a2, "*ooo-");
        patterns[53] = new Pattern(0x186a2, "*o-oo");
        patterns[54] = new Pattern(0x186a2, "*oo-o");
        patterns[55] = new Pattern(0x15f90, "*-ooo");
        patterns[56] = new Pattern(0x186a2, "o*-oo");
        patterns[57] = new Pattern(0x186a2, "o*o-o");
        patterns[58] = new Pattern(0x186a2, "o*oo-");
        patterns[59] = new Pattern(0x15f92, "-*ooo");
        patterns[60] = new Pattern(0x186a2, "-o*oo");
        patterns[61] = new Pattern(0x186a2, "o-*oo");
        patterns[62] = new Pattern(1002, "*o--o");
        patterns[63] = new Pattern(1000, "*-o-o");
        patterns[64] = new Pattern(1000, "*--oo");
        patterns[65] = new Pattern(1000, "*-oo-");
        patterns[66] = new Pattern(1502, "*oo--");
        patterns[67] = new Pattern(1002, "*o-o-");
        patterns[68] = new Pattern(1002, "o*--o");
        patterns[69] = new Pattern(1002, "o*-o-");
        patterns[70] = new Pattern(1002, "o*o--");
        patterns[71] = new Pattern(1000, "-*o-o");
        patterns[72] = new Pattern(1000, "-*-oo");
        patterns[73] = new Pattern(1502, "-*oo-");
        patterns[74] = new Pattern(1000, "o-*-o");
        patterns[75] = new Pattern(1002, "-o*-o");
        patterns[76] = new Pattern(1502, "oo*--");
        patterns[77] = new Pattern(1002, "-o*o-");
        patterns[78] = new Pattern(20000, "-*-oo-");
        patterns[79] = new Pattern(20000, "-*o-o-");
        patterns[80] = new Pattern(0x1876a, "-*oo--");
        patterns[81] = new Pattern(0x1876a, "--*oo-");
        patterns[82] = new Pattern(20002, "-o*-o-");
        patterns[83] = new Pattern(0x186a2, "-o*o--");
        patterns[84] = new Pattern(0x1876a, "--xx*-");
        patterns[85] = new Pattern(20000, "-x-x*-");
        patterns[86] = new Pattern(20000, "-xx-*-");
        patterns[87] = new Pattern(0x186a2, "--x*x-");
        patterns[88] = new Pattern(0x1876a, "-xx*--");
        patterns[89] = new Pattern(20002, "-x-*x-");
        patterns[90] = new Pattern(0x2dc6c0, "-*xxx-");
        patterns[91] = new Pattern(0x2dc6c0, "-x*xx-");
        patterns[92] = new Pattern(0x2dc6c0, "-*ooo-");
        patterns[93] = new Pattern(0x2dc6c0, "-o*oo-");
        patterns[94] = new Pattern(1000, "-*x---");
        patterns[95] = new Pattern(1000, "-*-x--");
        patterns[96] = new Pattern(1, "-*--x-");
        patterns[97] = new Pattern(1000, "-x*---");
        patterns[98] = new Pattern(1002, "--*x--");
        patterns[99] = new Pattern(1000, "--*-x-");
        patterns[100] = new Pattern(1000, "-*o---");
        patterns[101] = new Pattern(1000, "-*-o--");
        patterns[102] = new Pattern(1, "-*--o-");
        patterns[103] = new Pattern(1000, "-o*---");
        patterns[104] = new Pattern(1002, "--*o--");
        patterns[105] = new Pattern(1000, "--*-o-");
        int i = 0;
        do
            pts[i] = new Point(0, 0);
        while(++i < 16);
        i = 0;
        do
            index5[i] = 0;
        while(++i < 243);
        i = 0;
        do
            index6[i] = 0;
        while(++i < 729);
        i = 0;
        do
        {
            Pattern pattern = patterns[i];
            int j = pattern.v;
            if(pattern.length == 5)
            {
                if(index5[j] == 0)
                    index5[j] = i + 1;
                else
                    index5[j] = 150 * index5[j] + i + 1;
            } else
            if(pattern.length == 6)
                if(index6[j] == 0)
                    index6[j] = i + 1;
                else
                    index6[j] = 150 * index6[j] + i + 1;
        } while(++i < 106);
    }

    Point makeMove(int i, int ai[][])
    {
        for(int j = 0; j < i; j++)
        {
            for(int i1 = 0; i1 < i; i1++)
                weights[j][i1] = 0;

        }

        for(int k = 0; k < i; k++)
        {
            for(int j1 = 0; j1 < i; j1++)
                ComputeWeight(k, j1, i, ai);

        }

        int l1 = 0;
        int i2 = -1;
        for(int l = 0; l < i; l++)
        {
            for(int k1 = 0; k1 < i; k1++)
            {
                int j2 = weights[l][k1];
                if(j2 > i2)
                {
                    pts[0].x = l;
                    pts[0].y = k1;
                    l1 = 1;
                    i2 = j2;
                } else
                if(j2 == i2 && l1 < 16)
                {
                    pts[l1].x = l;
                    pts[l1].y = k1;
                    l1++;
                }
            }

        }

        int k2 = l1 != 1 ? RandNumber(l1) : 0;
        return new Point(pts[k2].x, pts[k2].y);
    }

    int ComputeIndex6(int i, int j, int k, int l, int ai[][])
    {
        l += (1 - ai[POSI(i, k, 5)][POSJ(j, k, 5)]) * 243;
        return l;
    }

    int POSI(int i, int j, int k)
    {
        return i + k * dirI[j];
    }

    int POSJ(int i, int j, int k)
    {
        return i + k * dirJ[j];
    }

    boolean ON_BOARD(int i, int j, int k)
    {
        return i >= 0 && j >= 0 && i < k && j < k;
    }

    int ComputeIndex5(int i, int j, int k, int ai[][])
    {
        int l = 0;
        int i1 = 1;
        int j1 = 0;
        do
        {
            l += (1 - ai[POSI(i, k, j1)][POSJ(j, k, j1)]) * i1;
            i1 *= 3;
        } while(++j1 < 5);
        return l;
    }

    public int weights[][];
    private final Pattern patterns[] = new Pattern[106];
    private final int dirI[] = new int[8];
    private final int dirJ[] = new int[8];    
    private final Point pts[] = new Point[16];
    private int kkk;
    private int mmm;
    private int nnn;
    private final int index5[] = new int[243];
    private final int index6[] = new int[729];
}